home *** CD-ROM | disk | FTP | other *** search
/ Aminet 41 / Aminet 41 (2001)(Schatztruhe)[!][Feb 2001].iso / Aminet / dev / c / libiconv_src.lha / src / iso2022_cnext.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-11-07  |  12.1 KB  |  464 lines

  1.  
  2. /*
  3.  * ISO-2022-CN-EXT
  4.  */
  5.  
  6. /* Specification: RFC 1922 */
  7.  
  8. #define ESC 0x1b
  9. #define SO  0x0e
  10. #define SI  0x0f
  11.  
  12. /*
  13.  * The state is composed of one of the following values
  14.  */
  15. #define STATE_ASCII          0
  16. #define STATE_TWOBYTE        1
  17. /*
  18.  * and one of the following values, << 8
  19.  */
  20. #define STATE2_NONE                   0
  21. #define STATE2_DESIGNATED_GB2312      1
  22. #define STATE2_DESIGNATED_CNS11643_1  2
  23. #define STATE2_DESIGNATED_ISO_IR_165  3
  24. /*
  25.  * and one of the following values, << 16
  26.  */
  27. #define STATE3_NONE                   0
  28. #define STATE3_DESIGNATED_CNS11643_2  1
  29. /*
  30.  * and one of the following values, << 24
  31.  */
  32. #define STATE4_NONE                   0
  33. #define STATE4_DESIGNATED_CNS11643_3  1
  34. #define STATE4_DESIGNATED_CNS11643_4  2
  35. #define STATE4_DESIGNATED_CNS11643_5  3
  36. #define STATE4_DESIGNATED_CNS11643_6  4
  37. #define STATE4_DESIGNATED_CNS11643_7  5
  38.  
  39. #define SPLIT_STATE \
  40.   unsigned int state1 = state & 0xff, state2 = (state >> 8) & 0xff, state3 = (state >> 16) & 0xff, state4 = state >> 24
  41. #define COMBINE_STATE \
  42.   state = (state4 << 24) | (state3 << 16) | (state2 << 8) | state1
  43.  
  44. static int
  45. iso2022_cn_ext_mbtowc (conv_t conv, wchar_t *pwc, const unsigned char *s, int n)
  46. {
  47.   state_t state = conv->istate;
  48.   SPLIT_STATE;
  49.   int count = 0;
  50.   unsigned char c;
  51.   for (;;) {
  52.     c = *s;
  53.     if (c == ESC) {
  54.       if (n < count+4)
  55.         goto none;
  56.       if (s[1] == '$') {
  57.         if (s[2] == ')') {
  58.           if (s[3] == 'A') {
  59.             state2 = STATE2_DESIGNATED_GB2312;
  60.             s += 4; count += 4;
  61.             if (n < count+1)
  62.               goto none;
  63.             continue;
  64.           }
  65.           if (s[3] == 'G') {
  66.             state2 = STATE2_DESIGNATED_CNS11643_1;
  67.             s += 4; count += 4;
  68.             if (n < count+1)
  69.               goto none;
  70.             continue;
  71.           }
  72.           if (s[3] == 'E') {
  73.             state2 = STATE2_DESIGNATED_ISO_IR_165;
  74.             s += 4; count += 4;
  75.             if (n < count+1)
  76.               goto none;
  77.             continue;
  78.           }
  79.         }
  80.         if (s[2] == '*') {
  81.           if (s[3] == 'H') {
  82.             state3 = STATE3_DESIGNATED_CNS11643_2;
  83.             s += 4; count += 4;
  84.             if (n < count+1)
  85.               goto none;
  86.             continue;
  87.           }
  88.         }
  89.         if (s[2] == '+') {
  90.           if (s[3] == 'I') {
  91.             state4 = STATE4_DESIGNATED_CNS11643_3;
  92.             s += 4; count += 4;
  93.             if (n < count+1)
  94.               goto none;
  95.             continue;
  96.           }
  97.           if (s[3] == 'J') {
  98.             state4 = STATE4_DESIGNATED_CNS11643_4;
  99.             s += 4; count += 4;
  100.             if (n < count+1)
  101.               goto none;
  102.             continue;
  103.           }
  104.           if (s[3] == 'K') {
  105.             state4 = STATE4_DESIGNATED_CNS11643_5;
  106.             s += 4; count += 4;
  107.             if (n < count+1)
  108.               goto none;
  109.             continue;
  110.           }
  111.           if (s[3] == 'L') {
  112.             state4 = STATE4_DESIGNATED_CNS11643_6;
  113.             s += 4; count += 4;
  114.             if (n < count+1)
  115.               goto none;
  116.             continue;
  117.           }
  118.           if (s[3] == 'M') {
  119.             state4 = STATE4_DESIGNATED_CNS11643_7;
  120.             s += 4; count += 4;
  121.             if (n < count+1)
  122.               goto none;
  123.             continue;
  124.           }
  125.         }
  126.       }
  127.       if (s[1] == 'N') {
  128.         switch (state3) {
  129.           case STATE3_NONE:
  130.             return RET_ILSEQ;
  131.           case STATE3_DESIGNATED_CNS11643_2:
  132.             if (s[2] < 0x80 && s[3] < 0x80) {
  133.               int ret = cns11643_2_mbtowc(conv,pwc,s+2,2);
  134.               if (ret == RET_ILSEQ)
  135.                 return RET_ILSEQ;
  136.               if (ret != 2) abort();
  137.               COMBINE_STATE;
  138.               conv->istate = state;
  139.               return count+4;
  140.             } else
  141.               return RET_ILSEQ;
  142.           default: abort();
  143.         }
  144.       }
  145.       if (s[1] == 'O') {
  146.         switch (state4) {
  147.           case STATE4_NONE:
  148.             return RET_ILSEQ;
  149.           case STATE4_DESIGNATED_CNS11643_3:
  150.             if (s[2] < 0x80 && s[3] < 0x80) {
  151.               int ret = cns11643_3_mbtowc(conv,pwc,s+2,2);
  152.               if (ret == RET_ILSEQ)
  153.                 return RET_ILSEQ;
  154.               if (ret != 2) abort();
  155.               COMBINE_STATE;
  156.               conv->istate = state;
  157.               return count+4;
  158.             } else
  159.               return RET_ILSEQ;
  160.           case STATE4_DESIGNATED_CNS11643_4:
  161.             if (s[2] < 0x80 && s[3] < 0x80) {
  162.               /* We don't have a CNS 11643-4 to Unicode table yet. */
  163.               return RET_ILSEQ;
  164.             } else
  165.               return RET_ILSEQ;
  166.           case STATE4_DESIGNATED_CNS11643_5:
  167.             if (s[2] < 0x80 && s[3] < 0x80) {
  168.               /* We don't have a CNS 11643-5 to Unicode table yet. */
  169.               return RET_ILSEQ;
  170.             } else
  171.               return RET_ILSEQ;
  172.           case STATE4_DESIGNATED_CNS11643_6:
  173.             if (s[2] < 0x80 && s[3] < 0x80) {
  174.               /* We don't have a CNS 11643-6 to Unicode table yet. */
  175.               return RET_ILSEQ;
  176.             } else
  177.               return RET_ILSEQ;
  178.           case STATE4_DESIGNATED_CNS11643_7:
  179.             if (s[2] < 0x80 && s[3] < 0x80) {
  180.               /* We don't have a CNS 11643-7 to Unicode table yet. */
  181.               return RET_ILSEQ;
  182.             } else
  183.               return RET_ILSEQ;
  184.           default: abort();
  185.         }
  186.       }
  187.       return RET_ILSEQ;
  188.     }
  189.     if (c == SO) {
  190.       if (state2 != STATE2_DESIGNATED_GB2312 && state2 != STATE2_DESIGNATED_CNS11643_1 && state2 != STATE2_DESIGNATED_ISO_IR_165)
  191.         return RET_ILSEQ;
  192.       state1 = STATE_TWOBYTE;
  193.       s++; count++;
  194.       if (n < count+1)
  195.         goto none;
  196.       continue;
  197.     }
  198.     if (c == SI) {
  199.       state1 = STATE_ASCII;
  200.       s++; count++;
  201.       if (n < count+1)
  202.         goto none;
  203.       continue;
  204.     }
  205.     break;
  206.   }
  207.   switch (state1) {
  208.     case STATE_ASCII:
  209.       if (c < 0x80) {
  210.         int ret = ascii_mbtowc(conv,pwc,s,1);
  211.         if (ret == RET_ILSEQ)
  212.           return RET_ILSEQ;
  213.         if (ret != 1) abort();
  214.         if (*pwc == 0x000a || *pwc == 0x000d) {
  215.           state2 = STATE2_NONE; state3 = STATE3_NONE; state4 = STATE3_NONE;
  216.         }
  217.         COMBINE_STATE;
  218.         conv->istate = state;
  219.         return count+1;
  220.       } else
  221.         return RET_ILSEQ;
  222.     case STATE_TWOBYTE:
  223.       if (n < count+2)
  224.         goto none;
  225.       if (s[0] < 0x80 && s[1] < 0x80) {
  226.         int ret;
  227.         switch (state2) {
  228.           case STATE2_NONE:
  229.             return RET_ILSEQ;
  230.           case STATE2_DESIGNATED_GB2312:
  231.             ret = gb2312_mbtowc(conv,pwc,s,2); break;
  232.           case STATE2_DESIGNATED_CNS11643_1:
  233.             ret = cns11643_1_mbtowc(conv,pwc,s,2); break;
  234.           case STATE2_DESIGNATED_ISO_IR_165:
  235.             ret = isoir165_mbtowc(conv,pwc,s,2); break;
  236.           default: abort();
  237.         }
  238.         if (ret == RET_ILSEQ)
  239.           return RET_ILSEQ;
  240.         if (ret != 2) abort();
  241.         COMBINE_STATE;
  242.         conv->istate = state;
  243.         return count+2;
  244.       } else
  245.         return RET_ILSEQ;
  246.     default: abort();
  247.   }
  248.  
  249. none:
  250.   COMBINE_STATE;
  251.   conv->istate = state;
  252.   return RET_TOOFEW(count);
  253. }
  254.  
  255. static int
  256. iso2022_cn_ext_wctomb (conv_t conv, unsigned char *r, wchar_t wc, int n)
  257. {
  258.   state_t state = conv->ostate;
  259.   SPLIT_STATE;
  260.   unsigned char buf[3];
  261.   int ret;
  262.  
  263.   /* Try ASCII. */
  264.   ret = ascii_wctomb(conv,buf,wc,1);
  265.   if (ret != RET_ILSEQ) {
  266.     if (ret != 1) abort();
  267.     if (buf[0] < 0x80) {
  268.       int count = (state1 == STATE_ASCII ? 1 : 2);
  269.       if (n < count)
  270.         return RET_TOOSMALL;
  271.       if (state1 != STATE_ASCII) {
  272.         r[0] = SI;
  273.         r += 1;
  274.         state1 = STATE_ASCII;
  275.       }
  276.       r[0] = buf[0];
  277.       if (wc == 0x000a || wc == 0x000d) {
  278.         state2 = STATE2_NONE; state3 = STATE3_NONE; state4 = STATE3_NONE;
  279.       }
  280.       COMBINE_STATE;
  281.       conv->ostate = state;
  282.       return count;
  283.     }
  284.   }
  285.  
  286.   /* Try GB 2312-1980. */
  287.   ret = gb2312_wctomb(conv,buf,wc,2);
  288.   if (ret != RET_ILSEQ) {
  289.     if (ret != 2) abort();
  290.     if (buf[0] < 0x80 && buf[1] < 0x80) {
  291.       int count = (state2 == STATE2_DESIGNATED_GB2312 ? 0 : 4) + (state1 == STATE_TWOBYTE ? 0 : 1) + 2;
  292.       if (n < count)
  293.         return RET_TOOSMALL;
  294.       if (state2 != STATE2_DESIGNATED_GB2312) {
  295.         r[0] = ESC;
  296.         r[1] = '$';
  297.         r[2] = ')';
  298.         r[3] = 'A';
  299.         r += 4;
  300.         state2 = STATE2_DESIGNATED_GB2312;
  301.       }
  302.       if (state1 != STATE_TWOBYTE) {
  303.         r[0] = SO;
  304.         r += 1;
  305.         state1 = STATE_TWOBYTE;
  306.       }
  307.       r[0] = buf[0];
  308.       r[1] = buf[1];
  309.       COMBINE_STATE;
  310.       conv->ostate = state;
  311.       return count;
  312.     }
  313.   }
  314.  
  315.   ret = cns11643_wctomb(conv,buf,wc,3);
  316.   if (ret != RET_ILSEQ) {
  317.     if (ret != 3) abort();
  318.  
  319.     /* Try CNS 11643-1992 Plane 1. */
  320.     if (buf[0] == 0 && buf[1] < 0x80 && buf[2] < 0x80) {
  321.       int count = (state2 == STATE2_DESIGNATED_CNS11643_1 ? 0 : 4) + (state1 == STATE_TWOBYTE ? 0 : 1) + 2;
  322.       if (n < count)
  323.         return RET_TOOSMALL;
  324.       if (state2 != STATE2_DESIGNATED_CNS11643_1) {
  325.         r[0] = ESC;
  326.         r[1] = '$';
  327.         r[2] = ')';
  328.         r[3] = 'G';
  329.         r += 4;
  330.         state2 = STATE2_DESIGNATED_CNS11643_1;
  331.       }
  332.       if (state1 != STATE_TWOBYTE) {
  333.         r[0] = SO;
  334.         r += 1;
  335.         state1 = STATE_TWOBYTE;
  336.       }
  337.       r[0] = buf[1];
  338.       r[1] = buf[2];
  339.       COMBINE_STATE;
  340.       conv->ostate = state;
  341.       return count;
  342.     }
  343.  
  344.     /* Try CNS 11643-1992 Plane 2. */
  345.     if (buf[0] == 1 && buf[1] < 0x80 && buf[2] < 0x80) {
  346.       int count = (state3 == STATE3_DESIGNATED_CNS11643_2 ? 0 : 4) + 4;
  347.       if (n < count)
  348.         return RET_TOOSMALL;
  349.       if (state3 != STATE3_DESIGNATED_CNS11643_2) {
  350.         r[0] = ESC;
  351.         r[1] = '$';
  352.         r[2] = '*';
  353.         r[3] = 'H';
  354.         r += 4;
  355.         state3 = STATE3_DESIGNATED_CNS11643_2;
  356.       }
  357.       r[0] = ESC;
  358.       r[1] = 'N';
  359.       r[2] = buf[1];
  360.       r[3] = buf[2];
  361.       COMBINE_STATE;
  362.       conv->ostate = state;
  363.       return count;
  364.     }
  365.  
  366.     /* Try CNS 11643-1992 Plane 3. */
  367.     if (buf[0] == 2 && buf[1] < 0x80 && buf[2] < 0x80) {
  368.       int count = (state4 == STATE4_DESIGNATED_CNS11643_3 ? 0 : 4) + 4;
  369.       if (n < count)
  370.         return RET_TOOSMALL;
  371.       if (state4 != STATE4_DESIGNATED_CNS11643_3) {
  372.         r[0] = ESC;
  373.         r[1] = '$';
  374.         r[2] = '+';
  375.         r[3] = 'I';
  376.         r += 4;
  377.         state4 = STATE4_DESIGNATED_CNS11643_3;
  378.       }
  379.       r[0] = ESC;
  380.       r[1] = 'O';
  381.       r[2] = buf[1];
  382.       r[3] = buf[2];
  383.       COMBINE_STATE;
  384.       conv->ostate = state;
  385.       return count;
  386.     }
  387.  
  388.     /* No table for CNS 11643-1992 Plane 4 yet. */
  389.  
  390.     /* No table for CNS 11643-1992 Plane 5 yet. */
  391.  
  392.     /* No table for CNS 11643-1992 Plane 6 yet. */
  393.  
  394.     /* No table for CNS 11643-1992 Plane 7 yet. */
  395.  
  396.   }
  397.  
  398.   /* Try ISO-IR-165. */
  399.   ret = isoir165_wctomb(conv,buf,wc,2);
  400.   if (ret != RET_ILSEQ) {
  401.     if (ret != 2) abort();
  402.     if (buf[0] < 0x80 && buf[1] < 0x80) {
  403.       int count = (state2 == STATE2_DESIGNATED_ISO_IR_165 ? 0 : 4) + (state1 == STATE_TWOBYTE ? 0 : 1) + 2;
  404.       if (n < count)
  405.         return RET_TOOSMALL;
  406.       if (state2 != STATE2_DESIGNATED_ISO_IR_165) {
  407.         r[0] = ESC;
  408.         r[1] = '$';
  409.         r[2] = ')';
  410.         r[3] = 'E';
  411.         r += 4;
  412.         state2 = STATE2_DESIGNATED_ISO_IR_165;
  413.       }
  414.       if (state1 != STATE_TWOBYTE) {
  415.         r[0] = SO;
  416.         r += 1;
  417.         state1 = STATE_TWOBYTE;
  418.       }
  419.       r[0] = buf[0];
  420.       r[1] = buf[1];
  421.       COMBINE_STATE;
  422.       conv->ostate = state;
  423.       return count;
  424.     }
  425.   }
  426.  
  427.   return RET_ILSEQ;
  428. }
  429.  
  430. static int
  431. iso2022_cn_ext_reset (conv_t conv, unsigned char *r, int n)
  432. {
  433.   state_t state = conv->ostate;
  434.   SPLIT_STATE;
  435.   (void)state2;
  436.   (void)state3;
  437.   (void)state4;
  438.   if (state1 != STATE_ASCII) {
  439.     if (n < 1)
  440.       return RET_TOOSMALL;
  441.     r[0] = SI;
  442.     /* conv->ostate = 0; will be done by the caller */
  443.     return 1;
  444.   } else
  445.     return 0;
  446. }
  447.  
  448. #undef COMBINE_STATE
  449. #undef SPLIT_STATE
  450. #undef STATE4_DESIGNATED_CNS11643_7
  451. #undef STATE4_DESIGNATED_CNS11643_6
  452. #undef STATE4_DESIGNATED_CNS11643_5
  453. #undef STATE4_DESIGNATED_CNS11643_4
  454. #undef STATE4_DESIGNATED_CNS11643_3
  455. #undef STATE4_NONE
  456. #undef STATE3_DESIGNATED_CNS11643_2
  457. #undef STATE3_NONE
  458. #undef STATE2_DESIGNATED_ISO_IR_165
  459. #undef STATE2_DESIGNATED_CNS11643_1
  460. #undef STATE2_DESIGNATED_GB2312
  461. #undef STATE2_NONE
  462. #undef STATE_TWOBYTE
  463. #undef STATE_ASCII
  464.